package org.jheuristics.ga.operators.selectors;

import org.epanetgrid.otimizacao.log.AGLogger;
import org.jheuristics.Individual;
import org.jheuristics.ga.GAConfig;
import org.jheuristics.ga.GAStatus;
import org.jheuristics.ga.Population;
import org.jheuristics.ga.multiObjective.DistanceAlgorithm;
import org.jheuristics.ga.operators.Selector;


/**
 * TODO
 *
 * @author Marcell Manfrin, marcell@ourgrid.org, Oct 28, 2005
 */
public abstract class AbstractDistanceSelector implements Selector {
	private DistanceAlgorithm densityAlgorithm;

	/**
	 * TODO
	 *
	 * @param densityAlgorithm
	 */
	public AbstractDistanceSelector(DistanceAlgorithm densityAlgorithm) {
		setDistanceAlgorithm(densityAlgorithm);
	}

	/**
	 * TODO
	 * Esta replicado em Group Selector pela questao do log do AG
	 * @param population
	 * @param howMany
	 * @param status
	 * @param config
	 * @return
	 * @see org.jheuristics.ga.operators.Selector#select(org.jheuristics.ga.Population, int, org.jheuristics.ga.GAStatus, org.jheuristics.ga.GAConfig)
	 */
	public Individual[] select(Population population, int howMany, GAStatus status, GAConfig config) {
		if (null == population) {
			throw new NullPointerException();
		}
		if (0 > howMany) {
			throw new IllegalArgumentException();
		}
		if (0 == howMany) {
			return new Individual[0];
		}
		if (population.size() <= howMany) {
			AGLogger.getInstance().debug("N�mero de indiv�duos "+population.size()+" menor ou igual a quantidade " +
					"a ser escolhida: "+howMany);
			return population.toIndividualArray();
		}
		return select(population.toIndividualArray(), howMany, status, config);
	}

	/**
	 * TODO
	 *
	 * @param individuals
	 * @param howMany
	 * @param status
	 * @param config
	 * @return
	 */
	protected abstract Individual[] select(Individual[] individuals, int howMany, GAStatus status, GAConfig config);

	/**
	 * TODO
	 *
	 * @return
	 */
	public DistanceAlgorithm getDistanceAlgorithm() {
		return densityAlgorithm;
	}

	/**
	 * TODO
	 *
	 * @param densityAlgorithm
	 */
	public void setDistanceAlgorithm(DistanceAlgorithm densityAlgorithm) {
		if (null == densityAlgorithm) {
			// TODO: ERROR MSG
			throw new NullPointerException();
		}
		this.densityAlgorithm = densityAlgorithm;
	}

}
